<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .style1{
            color:green;
        }

        .style2{
            color:red;
        }
    </style>
</head>
<body>
打字练习：<p id="test"></p>
<P>键入内容：
    <input name="textfield" type="text" size="50" onKeyDown="check()">
</P>
</body>
<script>
    function $(id){
        return document.getElementById(id);
    }

    var str="hello,welcome to study center!" //希望练习的内容
    window.onload =function(){
        var htmlstr="";
        for(var j=0;j<str.length;j++){
            htmlstr+="<span id='myspan"+j+"'/>"+str.substring(j,j+1)+"</span>";
        }
        $("test").innerHTML=htmlstr;
    }

    var i=0;


    function check(){
        /*
        arguments:该对象代表正在执行的函数和调用它的函数的参数。
        arguments.callee:返回正被执行的Function对象，也就是所指定的Function对象的正文。
        [function.]arguments.callee可选项
        function参数是当前正在执行的Function对象的名称。
        说明callee属性的初始值就是正被执行的Function对象。
        callee属性是arguments对象的一个成员，它表示对函数对象本身的引用，这有利于匿名
        函数的递归或者保证函数的封装性，还有需要注意的是callee拥有length属性，这个属性有时候
        用于验证还是比较好的。arguments.length是实参长度，arguments.callee.length是
        形参长度，由此可以判断调用时形参长度是否和实参长度一致。

        返回一个对函数的引用，该函数调用了当前函数。
            functionName.caller ：返回一个对函数的引用，该函数调用了当前函数
            functionName 对象是所执行函数的名称。
        对于函数来说，caller属性只有在函数执行时才有定义。如果函数是由顶层调用的，那么caller包含的就是null。如果在字符串上下文中使用caller属性，那么结果和functionName.toString 一样，也就是说，显示的是函数的反编译文本。
        onclick的第一个能数就是event，也就是arguments.callee.caller.arguments[0]这个。
        */
        var e=arguments.callee.caller.arguments[0]||window.event;
        var keycode=e.keyCode;

//fromCharCode() 可接受一个指定的 Unicode 值，然后返回一个字符串。
        var realkey=String.fromCharCode(keycode+32) ;
        if(str.substring(i,i+1)==realkey){
            $("myspan"+i).className='style1';
        }else{
            $("myspan"+i).className='style2';
        }
        i++;
    }
</script>

</html>